package service

import (
	"bytes"
	"errors"
	"net/http"
	"strconv"
	"strings"

	"gitee.com/wuzheng0709/backend-gopkg/infrastructure/connector/orm"
	"gitee.com/wuzheng0709/backend-gopkg/infrastructure/pkg/code"
	"gitee.com/wuzheng0709/backend-gopkg/infrastructure/pkg/gin/log"
	"gitee.com/wuzheng0709/backend-gopkg/infrastructure/pkg/toolfunc"
	"github.com/gin-gonic/gin"
	jsoniter "github.com/json-iterator/go"
)

var json = jsoniter.ConfigCompatibleWithStandardLibrary

const (
	// code.SUCCESS_CODE   = 0     //成功的状态码
	// BAD_LOGIN      = 10001 //登录失败
	// BAD_REQUEST    = 10002 //参数错误
	// PERMISSION_ERR = 10003 //权限校验错误
	// FAIL_CODE      = 20001 //失败的状态码
	BUSINESS_ERR = 20002 //业务错误
	// NULL_ERR       = 20003 //无数据错误
	// DATABASE_ERR   = 20004 //数据库异常
	// CACHE_ERR      = 20005 //缓存异常
	USER_UID_KEY           = "UID" //页面UUID键名
	SUPER_ADMIN_ID         = "10"  //超级管理员
	ReqSelKeyLimitLang int = 38    //首页搜索字数限制
)

type ListReq struct {
	Page      int    `json:"page" form:"page" `          //页数
	Num       int    `json:"num"  form:"num" `           //数量
	Key       string `json:"key" form:"key" `            //搜索关键字
	Sort      string `json:"sort" form:"sort"`           //排序字段
	OrderType string `json:"orderType" form:"orderType"` //排序规则
	BeginAt   string `json:"beginAt" form:"beginAt" `    //开始时间
	EndAt     string `json:"endAt" form:"endAt" `        //结束时间
	//Guid      string `json:"guid" form:"guid"`           // cm_proc_plan_in 专用
	//Type      string `json:"type" form:"type"`           // 搜索类型
}

type ListReqForApc struct {
	Num            int    `json:"num"  form:"num" `                           //数量
	Page           int    `json:"page" form:"page" `                          //页数
	BeginAt        string `json:"beginAt" form:"beginAt" `                    //开始时间
	EndAt          string `json:"endAt" form:"endAt" `                        //结束时间
	PlanInDetailID int64  `json:"plan_in_detail_id" form:"plan_in_detail_id"` // 采购详情ID
}

func (l *ListReqForApc) GetListQuery(c *gin.Context) (err error) {
	err = c.ShouldBind(l)
	if err != nil {
		return err
	}
	//给默认参数
	if l.Page == 0 {
		l.Page = 1
	}
	if l.Num == 0 {
		l.Num = 30
	}
	return
}

type ListReqAddOth struct {
	ListReq
	Guid        string `json:"guid" form:"guid"`
	ProjectCode string `json:"project_code" form:"project_code"`
}

func (l *ListReqAddOth) GetListQueryV4(c *gin.Context) (err error) {
	err = c.ShouldBind(l)
	if err != nil {
		return err
	}
	//给默认参数
	if l.Page == 0 {
		l.Page = 1
	}
	if l.Num == 0 {
		l.Num = 30
	}
	if l.Sort == "" {
		l.Sort = "CREATION_DATE"
	}
	if l.OrderType == "" {
		l.OrderType = "DESC"
	}
	if l.OrderType != "DESC" && l.OrderType != "ASC" {
		return errors.New("orderType 不是期望的值")
	}
	l.Sort = l.Sort + "  " + l.OrderType
	return
}

func (l *ListReq) GetListQueryV4(c *gin.Context) (err error) {
	err = c.ShouldBind(l)
	if err != nil {
		return err
	}
	// 给默认参数
	if l.Page == 0 {
		l.Page = 1
	}
	if l.Num == 0 {
		l.Num = 30
	}
	if l.Sort == "" {
		l.Sort = "CREATION_DATE"
	}
	if l.OrderType == "" {
		l.OrderType = "DESC"
	}
	if l.OrderType != "DESC" && l.OrderType != "ASC" {
		return errors.New("orderType 不是期望的值")
	}
	l.Sort = l.Sort + "  " + l.OrderType
	return
}

func (l *ListReq) GetListQueryV2(c *gin.Context) (err error) {
	err = c.ShouldBind(l)
	if err != nil {
		return err
	}
	//给默认参数
	if l.Page == 0 {
		l.Page = 1
	}
	if l.Num == 0 {
		l.Num = 30
	}
	if l.Sort == "" {
		l.Sort = "created_at"
	}
	if l.OrderType == "" {
		l.OrderType = "DESC"
	}
	if l.OrderType != "DESC" && l.OrderType != "ASC" {
		return errors.New("orderType 不是期望的值")
	}
	l.Sort = l.Sort + "  " + l.OrderType
	return
}

func (l *ListReq) GetListQuery(c *gin.Context) (err error) {
	err = c.ShouldBind(l)
	if err != nil {
		return err
	}
	//给默认参数
	if l.Page == 0 {
		l.Page = 1
	}
	if l.Num == 0 {
		l.Num = 30
	}
	if l.Sort == "" {
		l.Sort = "createdAt"
	}
	if l.OrderType == "" {
		l.OrderType = "DESC"
	}
	if l.OrderType != "DESC" && l.OrderType != "ASC" {
		return errors.New("orderType 不是期望的值")
	}
	l.Sort = l.Sort + "  " + l.OrderType
	return
}

type KnowledgeListReq struct {
	ListReq
	Guid string `json:"guid" form:"guid"` // cm_proc_plan_in 专用
	Type string `json:"type" form:"type"` // 搜索类型

	PartTreeId int64 `json:"part_tree_id" form:"part_tree_id"` // 构件专用字段
}

// 组装阿里云搜索sql(首页)
func (l *KnowledgeListReq) GetListQueryV3(c *gin.Context) (string, []string, error) {
	if err := c.ShouldBind(l); err != nil {
		log.Error("传入参数错误", err.Error())
		return "", nil, err
	}
	if l.Page == 0 {
		l.Page = 1
	}
	if l.Num == 0 {
		l.Num = 30
	}
	key := strings.Trim(l.Key, "[]")
	keyListSource := strings.Split(key, ",")
	keyList := make([]string, 0, len(keyListSource))
	//var ReqSelKeylang int
	for _, k := range keyListSource {
		k = strings.Trim(k, "\"")
		//ReqSelKeylang += utf8.RuneCountInString(k)
		//if ReqSelKeylang > ReqSelKeyLimitLang {
		//	return "", nil, errors.New("长度超出限制")
		//}
		keyList = append(keyList, k)
	}

	reQuery := l.RetAliyunSql(keyList).String()
	log.Info("opensearch 需要查询的sql语句为:", reQuery)
	return reQuery, keyList, nil
}

// 生成阿里云搜索引擎的sql
// TODO：待优化
func (l *KnowledgeListReq) RetAliyunSql(keyList []string) *bytes.Buffer {
	queryBuffer := bytes.Buffer{}
	queryBuffer.WriteString("config=start:" + strconv.FormatInt(int64((l.Page-1)*l.Num), 10) + ",hit:" + strconv.FormatInt(int64(l.Num), 10))
	if len(keyList) == 0 || keyList[0] == "" {
		if l.Type != "" {
			queryBuffer.WriteString(",format:fulljson&&query=knowledge_type:\"" + l.Type + "\"")
			if l.PartTreeId != 0 {
				queryBuffer.WriteString(" AND  param3:\"" + toolfunc.Int642String(l.PartTreeId) + "\"")
			}
		} else {
			queryBuffer.WriteString(",format:fulljson&&query=\"\"")
		}
	} else {
		queryBuffer.WriteString(",format:fulljson&&query=(")
		for i, k := range keyList {
			if i == len(keyList) {
				queryBuffer.WriteString("desc:\"" + k + "\" OR ")
			} else {
				queryBuffer.WriteString("desc:\"" + k + "\"")
			}
		}
		queryBuffer.WriteString(")")
		if l.Type != "" {
			queryBuffer.WriteString("AND knowledge_type:\"" + l.Type + "\"")
		}
		if l.PartTreeId != 0 {
			queryBuffer.WriteString("AND  param3:\"" + toolfunc.Int642String(l.PartTreeId) + "\"")
		}
	}
	return &queryBuffer
}

func (l *ListReq) GetPostListQuery(c *gin.Context) (err error) {
	//给默认参数
	if l.Page == 0 {
		l.Page = 1
	}
	if l.Num == 0 {
		l.Num = 30
	}
	if l.Sort == "" {
		l.Sort = "createdAt"
	}
	if l.OrderType == "" {
		l.OrderType = "DESC"
	}
	if l.OrderType != "DESC" && l.OrderType != "ASC" {
		return errors.New("orderType 不是期望的值")
	}
	l.Sort = l.Sort + "  " + l.OrderType
	return
}

// 请求公共结构体
type IdsReq struct {
	Ids []string `json:"Ids"  binding:"required" ` //id 列表
}

type ResponseModel struct {
	Code    int         `json:"code"`
	Message string      `json:"msg"`
	Data    interface{} `json:"data,omitempty"`
}

type ResponseModel1 struct {
	Code    int         `json:"code"`
	Message string      `json:"message"`
	Data    interface{} `json:"data,omitempty"`
}

// 返回结果只针对 采购推荐可视化 的 电信短信返回值
type ResponseModelByApc struct {
	ResponseModel
	Flag string `json:"flag"`
}

// 响应JSON数据
func ResJSON(c *gin.Context, status int, v interface{}) {
	c.JSON(status, v)
}

// 响应成功
func ResDataErrorMsg(c *gin.Context, msg string, v interface{}) {
	ret := ResponseModel{Code: BUSINESS_ERR, Message: msg, Data: v}
	ResJSON(c, http.StatusBadRequest, &ret)
}

// 响应成功
func ResSuccess(c *gin.Context, v interface{}) {
	ret := ResponseModel{Code: code.SUCCESS_CODE, Message: "ok", Data: v}
	ResJSON(c, http.StatusOK, &ret)
}

const ReturnSuccess = "S0000001"

func ResReturnCode(c *gin.Context, v interface{}) {
	ret := ReturnCode{Code: code.SUCCESS_CODE, Message: "处理成功", Data: v, ReturnCode: ReturnSuccess, ReturnDesc: "处理成功"}
	ResJSON(c, http.StatusOK, &ret)
}

type ReturnCode struct {
	ReturnCode string      `json:"RETURN_CODE"`
	ReturnDesc string      `json:"RETURN_DESC"`
	Code       int         `json:"code"`
	Message    string      `json:"msg"`
	Data       interface{} `json:"data,omitempty"`
}

// 响应成功
func ResDataSuccessMsg(c *gin.Context, msg string, v interface{}) {
	ret := ResponseModel{Code: code.SUCCESS_CODE, Message: msg, Data: v}
	ResJSON(c, http.StatusOK, &ret)
}

// 响应成功
func ResSuccessMsg(c *gin.Context, msg string) {
	ret := ResponseModel{Code: code.SUCCESS_CODE, Message: msg}
	ResJSON(c, http.StatusOK, &ret)
}

// 响应成功
func ResSuccessMsgWithData(c *gin.Context, msg string, data interface{}) {
	ret := ResponseModel{Code: code.SUCCESS_CODE, Message: msg, Data: data}
	ResJSON(c, http.StatusOK, &ret)
}

// 参数错误
func ResBadRequest(c *gin.Context, msg string) {
	ret := ResponseModel{Code: code.BUSINESS_ERR, Message: "" + msg}
	ResJSON(c, http.StatusBadRequest, &ret)
}

// ResSuccessMsgByApc 响应成功-只针对 采购推荐系统
func ResSuccessMsgByApc(c *gin.Context, msg, flag string, v interface{}) {
	ret := ResponseModelByApc{ResponseModel: ResponseModel{Code: code.SUCCESS_CODE, Message: msg, Data: v}, Flag: flag}
	ResJSON(c, http.StatusOK, &ret)
}

// ResBadRequestByApc 参数错误-只针对 采购推荐系统
func ResBadRequestByApc(c *gin.Context, msg string) {
	ret := ResponseModelByApc{ResponseModel: ResponseModel{Code: code.BUSINESS_ERR, Message: msg}, Flag: "F"}
	ResJSON(c, http.StatusBadRequest, &ret)
}

// 响应错误-自定义错误类型
func ResBusinessCustom(c *gin.Context, code int, msg string, v interface{}) {
	ret := ResponseModel{Code: code, Message: msg, Data: v}
	ResJSON(c, http.StatusOK, &ret)
}

// 参数错误
func ResBadRequestMsg(c *gin.Context, msg string, v interface{}) {
	ret := ResponseModel{Code: code.BUSINESS_ERR, Message: msg, Data: v}
	ResJSON(c, http.StatusBadRequest, &ret)
}

// 参数错误
func ResBadRequest1(c *gin.Context, msg string) {
	ret := ResponseModel1{Code: code.BUSINESS_ERR, Message: "" + msg}
	ResJSON(c, http.StatusBadRequest, &ret)
}

// 业务错误  提示错误信息
func ResBusinessP(c *gin.Context, msg string) {
	ret := ResponseModel{Code: code.BUSINESS_ERR, Message: msg}
	ResJSON(c, http.StatusBadRequest, &ret)
}

// 业务错误  提示错误信息
func ResBusinessButSuccessP(c *gin.Context, msg string) {
	ret := ResponseModel{Code: code.BUSINESS_ERR, Message: msg}
	ResJSON(c, http.StatusOK, &ret)
}

// 权限错误
func ResPermission(c *gin.Context, msg string) {
	ret := ResponseModel{Code: code.PERMISSION_ERR, Message: msg}
	ResJSON(c, http.StatusUnauthorized, &ret)
}

// 响应错误-服务端故障
func ResErrSrv(c *gin.Context) {
	ret := ResponseModel{Code: code.ServerError, Message: "未知数据错误"}
	ResJSON(c, http.StatusForbidden, &ret)
}

// 响应错误-用户端故障
func ResErrCli(c *gin.Context, err error) {
	ret := ResponseModel{Code: code.ServerError, Message: err.Error()}
	ResJSON(c, http.StatusForbidden, &ret)
}

type ResponsePageData struct {
	IndexPage orm.IndexPage `json:"index"`
	Res       interface{}   `json:"res"`
}

type ResponsePage struct {
	Code    int              `json:"code"`
	Message string           `json:"msg"`
	Data    ResponsePageData `json:"data"`
}

// 响应成功-分页数据
func ResSuccessPage(c *gin.Context, indexPage orm.IndexPage, list interface{}) {
	ret := ResponsePage{Code: code.SUCCESS_CODE, Message: "ok", Data: ResponsePageData{IndexPage: indexPage, Res: list}}
	ResJSON(c, http.StatusOK, &ret)
}

// 响应成功-无数据
func ResSuccessMsgOfNullErr(c *gin.Context, msg string, v interface{}) {
	ret := ResponseModel{Code: code.NULL_ERR, Message: msg, Data: v}
	ResJSON(c, http.StatusOK, &ret)
}

// 响应JSON数据
func ResXML(c *gin.Context, status int, v interface{}) {
	c.XML(status, v)
}

// 响应成功
func ResXmlSuccessReS(c *gin.Context, v interface{}) {
	ResXML(c, http.StatusOK, &v)
}

// 错误返回
func ResXmlBadRes(c *gin.Context, v interface{}) {
	ResXML(c, http.StatusBadRequest, &v)
}

//// 带msg的错误返回
//func ResXmlBadResWithMsg(c *gin.Context, msg string) {
//	v := res.RetMainDataMarXmlResponse(req.MainDataManagerPubReqOfXML[any]{}, errors.New(msg), res.NewItemRes(0).Finish())
//	ResXML(c, http.StatusBadRequest, &v)
//}
